#include "StdAfx.h"
#include "ejc.h"


/////////////////////////////////////////////////////////////
CUITile::CUITile() : CRect(0,0,0,0)
{
	bkgndFill = 0;
	bkgndColor = RGB(0,32,32);
	boundLine = 0;
	boundColor = RGB(128,128,128);
}

CUITile::~CUITile()
{

}

void CUITile::Draw(CDC* pDC)
{
	if (bkgndFill)
	{
		pDC->FillSolidRect(this,bkgndColor);
	}
	if (boundLine)
	{
		pDC->Draw3dRect(this,boundColor,boundColor);
	}
//	CUILayout::Draw(pDC);
}

void CUITile::Recalc(const CRect& rc)
{
//	CUILayout::Recalc(rc);
	CRect::CopyRect(rc);
	
	inBound.CopyRect(this);
	inBound.DeflateRect(1,1,1,1);
}

BOOL CUITile::HitTest(const CPoint& pt) const
{
	return CRect::PtInRect(pt);
}
/////////////////////////////////////////////////////////////
CUILayout::CUILayout()
{
	int i,j;

	rows = 1;
	cols = 1;

	for(i = 0;i<MAX_UI_ROW;i++)
	{
		for(j = 0;j<MAX_UI_COL;j++)
		{
			cell[i][j] = NULL;
		}
	}

//	cellWidth = new long[cols];
//	cellHeight = new long[rows];
	for(i = 0;i<cols;i++)
	{
		cellWidth[i] = 0;
	}
	for(i = 0;i<rows;i++)
	{
		cellHeight[i] = 0;
	}
}

CUILayout::~CUILayout()
{
	rows = 0;
	cols = 0;

//	delete[] cellWidth;
//	delete[] cellHeight;
//	cellWidth=NULL;
//	cellHeight=NULL;

}

void CUILayout::BeginLayout(int numRow,int numCol)
{
	int i;
	if (numCol>0)
	{
		cols = numCol;
	}
	if (numRow>0)
	{
		rows = numRow;
	}

//	delete[] cellWidth;
//	delete[] cellHeight;

//	cellWidth = new long[cols];
//	cellHeight = new long[rows];
	for(i = 0;i<cols;i++)
	{
		cellWidth[i] = 0;
	}
	for(i = 0;i<rows;i++)
	{
		cellHeight[i] = 0;
	}
}

void CUILayout::SetChild(CUITile* layoutCell,int row,int col,int width,int height)
{
	if (row>=0&&row<rows&&col>=0&&col<cols)
	{
		cell[row][col] = layoutCell;
		cellWidth[col] = width;
		cellHeight[row] = height;
	}
}

void CUILayout::EndLayout()
{
	
}

void CUILayout::Recalc(const CRect& rc)
{
	int i,j;
	CRect r;
	int num;
	double x0,y0,x1,y1;
	double fixedWidth = 0;	
	double floatWidth = 0;
	double fixedHeight = 0;
	double floatHeight = 0;

	CUITile::Recalc(rc);

	num = 0;
	for(i = 0;i<cols;i++)
	{
		if (cellWidth[i])
		{
			fixedWidth += cellWidth[i];
			num++;
		}
	}
	if (num<cols)
	{
		floatWidth = ((double)Width()-fixedWidth)/(double)(cols-num);
	}

	num = 0;
	for(i = 0;i<rows;i++)
	{
		if (cellHeight[i])
		{
			fixedHeight += cellHeight[i];
			num++;
		}
	}
	if (num<rows)
	{
		floatHeight = ((double)Height()-fixedHeight)/(double)(rows-num);
	}

	y0 = top;
	for(i = 0;i<rows;i++)
	{
		if (cellHeight[i])
		{
			y1 = y0 + cellHeight[i];
		}
		else
		{
			y1 = y0 + floatHeight;
		}
		x0 = left;
		for(j = 0;j<cols;j++)
		{
			if (cellWidth[j])
			{
				x1 = x0 + cellWidth[j];
			}
			else
			{
				x1 = x0 + floatWidth;
			}

			r.SetRect(x0,y0,x1,y1);
			if (cell[i][j]!=NULL)
			{
				cell[i][j]->Recalc(r);
			}
			x0 = x1;
		}
		y0 = y1;
	}
}

void CUILayout::Draw(CDC* pDC)
{
	int i,j;

	CUITile::Draw(pDC);

	for(i = 0;i<rows;i++)
	{
		for(j = 0;j<cols;j++)
		{
			if (cell[i][j]!=NULL)
			{
				cell[i][j]->Draw(pDC);
			}
		}
	}

	PostPaint(pDC);
}

void CUILayout::PostPaint(CDC* pDC)
{

}

BOOL CUILayout::HitTest(const CPoint& pt) const
{
	int i,j;
	BOOL hit = FALSE;

	if (CUITile::HitTest(pt))
	{
		for(i = 0;i<rows&&!hit;i++)
		{
			for(j = 0;j<cols&&!hit;j++)
			{
				if (cell[i][j]!=NULL)
				{
					if (cell[i][j]->HitTest(pt))
					{
						hit = TRUE;
					}
				}
			}
		}
	}

	if (!hit)
	{
		hit = CUITile::HitTest(pt);
	}

	return hit;
}


/////////////////////////////////////////////////////////////
CMetroLayout::CMetroLayout()
{
	Init(0,0,0,0);
	clip.CreateRectRgn(0,0,0,0);

	numRow = 0;
	numCol = 0;
}

CMetroLayout::~CMetroLayout()
{
	clip.DeleteObject();
}

void CMetroLayout::Init(BYTE horz,BYTE vert,long cx,long cy)
{
	allowHorz = horz;
	allowVert = vert;
	size.cx = cx;
	size.cy = cy;
	diff.cx = 0;
	diff.cy = 0;
}

void CMetroLayout::Reset()
{
	diff.cx = 0;
	diff.cy = 0;
	Recalc(*this);
}

void CMetroLayout::SkipToHead()
{
	if (allowHorz)
	{
		diff.cx = 0;
	}
	if (allowVert)
	{
		diff.cy = 0;
	}
	Recalc(*this);
	if (allowHorz)
	{
		PostSlideHorz(+1);
	}
}

void CMetroLayout::SkipToPrev()
{
	if (allowHorz)
	{
		diff.cx += size.cx;
	}
	if (allowVert)
	{
		diff.cy += size.cy;
	}
	Recalc(*this);
	if (allowHorz)
	{
		PostSlideHorz(+1);
	}
}

void CMetroLayout::SkipToNext()
{
	if (allowHorz)
	{
		diff.cx -= size.cx;
	}
	if (allowVert)
	{
		diff.cy -= size.cy;
	}
	Recalc(*this);
	if (allowHorz)
	{
		PostSlideHorz(-1);
	}
}

void CMetroLayout::SkipTo(DWORD index)
{
//	int npp;

	if (allowHorz)
	{
//		npp = CRect::Width()/size.cx;
		diff.cx = -size.cx*index;
	}
	if (allowVert)
	{
//		npp = CRect::Height()/size.cy;
		diff.cy = -size.cy*index;
	}
	Recalc(*this);
	if (allowHorz)
	{
		PostSlideHorz(+1);
	}
}

void CMetroLayout::SkipToLast(DWORD num)
{
	int npp;

	if (allowHorz)
	{
		npp = CRect::Width()/size.cx;
		diff.cx = -size.cx*(num-npp);
	}
	if (allowVert)
	{
		npp = CRect::Height()/size.cy;
		diff.cy = -size.cy*(num-npp);
	}
	Recalc(*this);
	if (allowHorz)
	{
		PostSlideHorz(+1);
	}
}

// allow horz slide
// recalc layout on fixed horz & float vert
void CMetroLayout::RecalcHorz(const CRect& rc)
{
	int i,j;
	CRect r;
	int num = 0;
	double x0,y0,x1,y1;
	double floatHeight = 0;
	double fixedHeight = 0;

	for(i = 0;i<rows;i++)
	{
		if (cellHeight[i])
		{
			fixedHeight += cellHeight[i];
			num++;
		}
	}
	if (num<rows)
	{
		floatHeight = ((double)Height()-fixedHeight)/(double)(rows-num);
	}
	
	minVisCol = 999;
	maxVisCol = -1;
	x0 = left + diff.cx;
	for(i = 0;i<cols;i++)
	{
		x1 = x0 + size.cx;
		y0 = top + diff.cy;
		for(j = 0;j<rows;j++)
		{
			if (cellHeight[i])
			{
				y1 = y0 + cellHeight[i];
			}
			else
			{
				y1 = y0 + floatHeight;
			}

			r.SetRect(x0,y0,x1,y1);
			if (cell[j][i]!=NULL)
			{
				cell[j][i]->Recalc(r);
			}
			y0 = y1;
		}
		if (i<minVisCol && (x1>=rc.left&&x1<rc.right))
		{
			minVisCol = i;
		}
		if (maxVisCol<i && (x0>=rc.left&&x0<rc.right))
		{
			maxVisCol = i;
		}
		x0 = x1;
	}
//	TRACE("col %d-%d\r\n",minVisCol,maxVisCol);
}

// allow vert slide
// recalc layout on fixed vert & float horz
void CMetroLayout::RecalcVert(const CRect& rc)
{
	int i,j;
	CRect r;
	int num = 0;	
	double x0,y0,x1,y1;
	double floatWidth = 0;
	double fixedWidth = 0;

	for(i = 0;i<cols;i++)
	{
		if (cellWidth[i])
		{
			fixedWidth += cellWidth[i];
			num++;
		}
	}
	if (num<cols)
	{
		floatWidth = ((double)Width()-fixedWidth)/(double)(cols-num);
	}

	minVisRow = 999;
	maxVisRow = -1;
	y0 = top + diff.cy;
	for(i = 0;i<rows;i++)
	{
		y1 = y0 + size.cy;
		x0 = left + diff.cx;
		for(j = 0;j<cols;j++)
		{
			if (cellWidth[i])
			{
				x1 = x0 + cellWidth[i];
			}
			else
			{
				x1 = x0 + floatWidth;
			}

			r.SetRect(x0,y0,x1,y1);

			if (cell[i][j]!=NULL)
			{
				cell[i][j]->Recalc(r);
			}
			x0 = x1;
		}
		if (i<minVisRow && (y0>=rc.top&&y0<rc.bottom))
		{
			minVisRow = i;
		}
		if (maxVisRow<i && (y1>=rc.top&&y1<rc.bottom))
		{
			maxVisRow = i;
		}
		y0 = y1;
	}
}

// rc : visible rect
void CMetroLayout::Recalc(const CRect& rc)
{
	clip.SetRectRgn(&rc);

	if (allowHorz||allowVert)
	{
		CRect::CopyRect(rc);
		if (allowHorz)
		{
			RecalcHorz(rc);
		}
		if (allowVert)
		{
			RecalcVert(rc);
		}
	}
	else
	{
		CUILayout::Recalc(rc);
	}
}

void CMetroLayout::Draw(CDC* pDC)
{
	if (allowHorz || allowVert)
	{
		pDC->SelectClipRgn(&clip);
	}

	CUILayout::Draw(pDC);

	if (allowHorz || allowVert)
	{
		pDC->SelectClipRgn(NULL);
	}
}

void CMetroLayout::PostSlideHorz(short zDelta)
{
	int i;
	int cx;
	int x0,x1;
//	BOOL avail = CRect::PtInRect(pt);
	int offset = 100;
	int dx = CRect::Width();
	int lms = CRect::left-dx;	// left most side
	int lls = CRect::left-dx/2;	// left least side
	int rls = CRect::right+dx/2;// right least side
	int rms = CRect::right+dx;	// right most side

	for(i = 0;i<cols;i++)
	{
		x0 = left + diff.cx + i*size.cx;
		x1 = x0 + size.cx;
		cx = (x0+x1)/2;
		if (zDelta<0)	// move leftward
		{
			if (x1>lms && x1<lls)
			{
				OnLeaveHorz(i);
			}
			if (x1>lls&& x0<rms)
			{
				OnEnterHorz(i);
			}
		}
		else	// move rightward
		{
			if (x1>lms && x0<rls)
			{
				OnEnterHorz(i);
			}
			if (x0>rls&&x0<rms)
			{
				OnLeaveHorz(i);
			}
		}
	}
}

BOOL CMetroLayout::OnMouseHWheel(UINT nFlags, short zDelta, CPoint pt)
{
//	int i;
//	int cx;
//	int x0,x1;
	int offset = 90;
	long viewWidth = CRect::Width();
	BOOL avail = CRect::PtInRect(pt);
//	int dx = CRect::Width();
//	int lms = CRect::left-dx;	// left most side
//	int lls = CRect::left-dx/2;	// left least side
//	int rls = CRect::right+dx/2;// right least side
//	int rms = CRect::right+dx;	// right most side

	if (avail)
	{
		if (allowHorz)
		{
			// left : <0
			// right : >0
			diff.cx = (zDelta>0)?(diff.cx+offset):(diff.cx-offset);
			if (numCol>0)
			{
				if (zDelta>0 && diff.cx>0)	// most rightward
				{
					diff.cx = 0;
				}
				if (zDelta<0 && diff.cx<-numCol*size.cx+viewWidth)	// most leftward
				{
					diff.cx = -numCol*size.cx+viewWidth;
				}
			}
			RecalcHorz(*this);
			PostSlideHorz(zDelta);
		}
	}
	return avail;
}

BOOL CMetroLayout::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
	int offset = 80;
	long viewHeight = CRect::Height();
	BOOL avail = CRect::PtInRect(pt);
	if (avail)
	{
		if (allowVert)
		{
			diff.cy = (zDelta<0)?(diff.cy+offset):(diff.cy-offset);
			if (numRow>0)
			{
				if (zDelta<0 && diff.cy>0)	// most downward
				{
					diff.cy = 0;
				}
				if (zDelta>0 && diff.cy<-numRow*size.cy+viewHeight)	// most upward
				{
					diff.cy = -numRow*size.cy+viewHeight;
				}
			}
			RecalcVert(*this);
		}
	}
	return avail;
}

void CMetroLayout::OnEnterHorz(int col)
{
}

void CMetroLayout::OnLeaveHorz(int col)
{
}

void CMetroLayout::OnEnterVert(int row)
{
}

void CMetroLayout::OnLeaveVert(int row)
{
}

/////////////////////////////////////////////////////////////
CUIShell* CUIShell::usInst[256]={NULL};
BYTE CUIShell::usidInView=0;

void CUIShell::Reset()
{
	int i;
	for(i = 0;i<256;i++)
	{
		usInst[i] = NULL;
	}
}

CUIShell* CUIShell::Use(BYTE uiID)
{
	usidInView = uiID;

	return GetInstance();
}

CUIShell* CUIShell::GetInstance()
{
	return usInst[usidInView];
}

CUIShell::CUIShell(BYTE uiID)
{
	id = uiID;
	pt0.x = -1;
	pt0.y = -1;

	CUITile::bkgndFill = 1;

	CUIShell::usInst[id] = this;
}

CUIShell::~CUIShell()
{
}

void CUIShell::OnInitialUpdate(const CRect& rc)
{
	CUITile::Recalc(rc);
}

void CUIShell::Activate(DWORD param,DWORD flags)
{
	pressed = FALSE;
}

BOOL CUIShell::OnMouseHWheel(UINT nFlags,short zDelta, CPoint pt)
{
	return FALSE;
}

BOOL CUIShell::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
	return FALSE;
}

BOOL CUIShell::OnLButtonDown(UINT nFlags, CPoint point)
{
	pt0 = point;
	pressed = TRUE;
	return FALSE;
}

BOOL CUIShell::OnMouseMove(UINT nFlags,CPoint point)
{
	return FALSE;
}

BOOL CUIShell::OnLButtonUp(UINT nFlags,CPoint point)
{
	pressed = FALSE;
	return FALSE;
}

BOOL CUIShell::OnLButtonDblClk(UINT nFlags,CPoint point)
{
	return FALSE;
}

BOOL CUIShell::OnTimer()
{
	return FALSE;
}

BOOL CUIShell::OnTouchZoom(CPoint point,double ratio)
{
	return FALSE;
}

CJPEGTile::CJPEGTile()
{
//	CUITile::boundLine = 0;
//	CUITile::bkgndFill = 0;
	padding = 5;
}

void CJPEGTile::Activate(LPCSTR path)
{
	CString dst = path;

	if (dst.Compare(image.path)!=0)
	{
		image.UnLoad();
		image.path = path;
		image.Load();
	}
}

void CJPEGTile::UnActive()
{
	image.UnLoad();
}

void CJPEGTile::Draw(CDC* pDC)
{
	double df;
	double sf;
//	double mw,mh;
	double f;
	double dx,dy;
	double cx,cy;
	CRect rc;
	CRect dst;

	rc.CopyRect(&inBound);
	rc.DeflateRect(padding,padding,padding,padding);

	if (bkgndFill)
	{
		pDC->FillSolidRect(&inBound,bkgndColor);
	}
	if (boundLine)
	{
		pDC->Draw3dRect(&inBound,boundColor,boundColor);
	}
//	CUITile::Draw(pDC);

	if (image.IsLoaded())
	{
		pDC->SetStretchBltMode(HALFTONE);

		// auto fit
//		mw = min(image.sizeInPix.cx,rc.Width());
//		mh = min(image.sizeInPix.cy,rc.Height());
		sf = (double)image.sizeInPix.cx / (double)image.sizeInPix.cy;
		df = (double)rc.Width()/(double)rc.Height();

		f = min(sf,df);

		if (sf>df)	// src wider than dst
		{
			// use dst width
			cx = (double)rc.Width();
			cy = cx/sf;
			dx = 0;
			dy = (double)(rc.Height() - cy)/2.0;
		}
		else // dst wider than src
		{
			// use dst height
			cy = (double)rc.Height();
			cx = cy*sf;
			dy = 0;
			dx = (double)(rc.Width() - cx)/2.0;
		}
/*
		if (f>1.0)	// horz
		{
			cx = (double)rc.Width();
			cy = cx/f;
			dx = 0;
			dy = (double)(rc.Height() - cy)/2.0;
		}
		else	// vert
		{
			cy = (double)rc.Height();
			cx = cy*f;
			dy = 0;
			dx = (double)(rc.Width() - cx)/2.0;
		}
*/
		dst.SetRect(rc.left+dx,rc.top+dy,rc.left+dx+cx,rc.top+dy+cy);

		::StretchDIBits( pDC->m_hDC,
			rc.left + dx, rc.top + dy, cx, cy,
			0, 0, image.sizeInPix.cx, image.sizeInPix.cy,
			image.jcp.DIBBytes , &image.bmi, 
			DIB_RGB_COLORS, SRCCOPY );
		pDC->Draw3dRect(&dst,RGB(200,200,200),RGB(50,50,50));

//		pDC->Draw3dRect(&dst,RGB(192,255,192),RGB(192,255,192));
	}

//	if (boundLine)
//	{
//		pDC->Draw3dRect(this,boundColor,boundColor);
//	}

}

CZoomTile::CZoomTile()
{
	dst.SetRectEmpty();
	src.SetRectEmpty();

	clip.CreateRectRgn(0,0,0,0);
}

CZoomTile::~CZoomTile()
{
	clip.DeleteObject();
}

void CZoomTile::Extend(const CPoint &sc,const CSize& sz,double ratio,const CPoint& dc,CRect& dst)
{
//	CPoint sc = clip.CenterPoint();
	double dw = sz.cx * ratio;
	double dh = sz.cy * ratio;
	double x0 = sc.x * ratio;
	double x1 = dw - x0;
	double y0 = sc.y * ratio;
	double y1 = dh - y0;

//	dst.left = dc.x - sc.x*ratio;
//	dst.right = dc.x + (sz.cx-sc.x)*ratio;
//	dst.top = dc.y - (sc.y)*ratio;
//	dst.bottom = dc.y + (sz.cy-sc.y)*ratio;

	dst.left = dc.x - x0;
	dst.right = dc.x + x1;
	dst.top = dc.y - y0;
	dst.bottom = dc.y + y1;
}
/*
void CZoomTile::Normalize(const CRect& rc,double f,CRect& s,CRect& d)
{
	// intersect
	if (d.top < rc.top)
	{
		// chop top
		s.top += (double)(rc.top - d.top)/f;
		d.top = rc.top;
	}
	if (d.bottom > rc.bottom)
	{
		// chop bottom
		s.bottom -= (double)(d.bottom - rc.bottom)/f;
		d.bottom = rc.bottom;
	}
	if (d.left < rc.left)
	{
		// chop left
		s.left += (double)(rc.left - d.left)/f;
		d.left = rc.left;
	}
	if (d.right > rc.right)
	{
		s.right -= (double)(d.right - rc.right)/f;
		d.right = rc.right;
	}
}

void CZoomTile::Normalize(double f,const CRect& rcExtSrc,CRect& rcVisSrc,const CRect& rcClip,const CRect& rcExtDst,CRect& rcVisDst)
{
	long dx,dy;

	rcVisDst.left = max(rcExtDst.left,rcClip.left);
	rcVisSrc.left = rcExtSrc.left + (double)(rcVisDst.left - rcExtDst.left)/f;

	rcVisDst.right = min(rcExtDst.right,rcClip.right);
	rcVisSrc.right = rcExtSrc.right - (double)(rcExtDst.right - rcVisDst.right)/f;

	rcVisDst.top = max(rcExtDst.top,rcClip.top);
	rcVisSrc.top = rcExtSrc.top + (double)(rcVisDst.top - rcExtDst.top)/f;

	rcVisDst.bottom = min(rcExtDst.bottom,rcClip.bottom);
	rcVisSrc.bottom = rcExtSrc.bottom - (double)(rcExtDst.bottom - rcVisDst.bottom)/f;
}
*/
void CZoomTile::AutoFit()
{
	CRect rc;
//	ratio = 1.0;
//	double f = 1.0;

	rc.CopyRect(&inBound);
	rc.DeflateRect(padding,padding,padding,padding);
	// fit to width
	if (image.IsLoaded())
	{
		// clip in src
		src.SetRect(0,0,image.sizeInPix.cx,image.sizeInPix.cy);

		if (image.sizeInPix.cx > image.sizeInPix.cy)
		{
			ratio = (double)rc.Width() / (double)src.Width();
		}
		else
		{
			ratio = (double)rc.Height() / (double)src.Height();
		}
		fitRatio = ratio;

		// extend to dst
		Extend(src.CenterPoint(),image.sizeInPix,fitRatio,rc.CenterPoint(),ext);
//		ext = dst;

		// normalize src
//		Normalize(rc,f,src,dst);
//		ratio = f;
//		cen = src.CenterPoint();
	}
}

void CZoomTile::Pan(long dx,long dy)
{
	if (image.IsLoaded())
	{
		ext.OffsetRect(dx,dy);
	}
}

void CZoomTile::Focus(const CPoint &pt)
{
	long dx,dy;
	CRect rc;

	rc.CopyRect(&inBound);
	rc.DeflateRect(padding,padding,padding,padding);

	if (image.IsLoaded())
	{
		ratio = 1.0;
		Extend(src.CenterPoint(),image.sizeInPix,ratio,rc.CenterPoint(),ext);
/*
		if (ext.PtInRect(pt))
		{
			dx = rc.CenterPoint().x - pt.x;
			dy = rc.CenterPoint().y - pt.y;
			ext.OffsetRect(dx,dy);
		}
*/
	}
}

void CZoomTile::Zoom(CPoint pt,double f)
{
	CRect rc;
	CPoint sc;

//	cen = pt;
	rc.CopyRect(&inBound);
	rc.DeflateRect(padding,padding,padding,padding);
	if (image.IsLoaded())
	{
		if (ext.PtInRect(pt))
		{
			sc.x = (pt.x - ext.left)/ratio;
			sc.y = (pt.y - ext.top)/ratio;

			f = min(f,2.0);
			f = max(f,0.5);
			ratio = ratio*f;
			ratio = min(ratio,2.5);
			ratio = max(ratio,fitRatio);
			Extend(sc,image.sizeInPix,ratio,pt,ext);
/*		
//			dx = sx*ratio + ext.left;
			dw = image.sizeInPix.cx*ratio;
			dh = image.sizeInPix.cy*ratio;
			x0 = sx * ratio;
			x1 = dw - x0;
			y0 = sy * ratio;
			y1 = dh - y0;

			ext.left = pt.x - x0;
			ext.right = pt.x + x1;
			ext.top = pt.y - y0;
			ext.bottom = pt.y + y1;
*/
		}
	}
}

void CZoomTile::Activate(LPCSTR path)
{
	CRect rc;
	double f = 1.0;

	rc.CopyRect(&inBound);
	rc.DeflateRect(padding,padding,padding,padding);
	clip.SetRectRgn(&rc);

	CJPEGTile::Activate(path);

	AutoFit();
}

void CZoomTile::Draw(CDC* pDC)
{
//	CRect rc;

	if (bkgndFill)
	{
		pDC->FillSolidRect(&inBound,bkgndColor);
	}
	if (boundLine)
	{
		pDC->Draw3dRect(&inBound,boundColor,boundColor);
	}
	if (image.IsLoaded())
	{
		pDC->SelectClipRgn(&clip);
		pDC->SetStretchBltMode(HALFTONE);
		::StretchDIBits( pDC->m_hDC,
//			dst.left, dst.top, dst.Width(), dst.Height(),
			ext.left, ext.top, ext.Width(), ext.Height(),
			src.left, src.top, src.Width(), src.Height(),
			image.jcp.DIBBytes , &image.bmi, 
			DIB_RGB_COLORS, SRCCOPY );
		pDC->Draw3dRect(&ext,RGB(200,200,200),RGB(50,50,50));

		pDC->SelectClipRgn(NULL);

//		rc.SetRect(cen,cen);
//		rc.InflateRect(4,4,4,4);
//		pDC->FillSolidRect(&rc,RGB(255,192,192));
	}
}

CIconTile::CIconTile()
{
	CJPEGTile::padding = 0;

	boundLine = 1;
	bkgndFill = 1;
	bkgndColor = RGB(192,128,50);
}

void CIconTile::Init(LPCSTR fn,int cx,int cy,BYTE s)
{
	status = 0xFF;
	size.cx = cx;
	size.cy = cy;
	path[UICTL_DISABLE].Format("%s_d.jpg",fn);
	path[UICTL_ENABLE].Format("%s_e.jpg",fn);
	path[UICTL_CHECKED].Format("%s_c.jpg",fn);

	SetStatus(s);
}

void CIconTile::SetStatus(BYTE s)
{
	if (status!=s)
	{
		status = s;
		CJPEGTile::Activate(path[status]);
	}
}

void CIconTile::Recalc(const CRect& rc)
{
	int cx,cy;

	CJPEGTile::Recalc(rc);

	cx = CRect::CenterPoint().x;
	cy = CRect::CenterPoint().y;
	inBound.left = cx - size.cx/2;
	inBound.right = inBound.left + size.cx;
	inBound.top = cy - size.cy/2;
	inBound.bottom = inBound.top + size.cy;
}

CFlipTile::CFlipTile()
{
}

CFont* CTextTile::UseFont(BYTE f)
{
	CFont* pf = NULL;

	switch(f)
	{
	case FONT_MEDIUM:
		pf = &CTextTile::ftM;
		break;
	case FONT_LARGE:
		pf = &CTextTile::ftL;
		break;
	case FONT_SMALL:
	default:
		pf = &CTextTile::ftS;
		break;
	}

	return pf;
}

CFont CTextTile::ftS;	// small
CFont CTextTile::ftM;	// medium
CFont CTextTile::ftL;	// large + bold

CTextTile::CTextTile()
{
	size = FONT_SMALL;
	style = (DT_CENTER|DT_VCENTER|DT_SINGLELINE);
	textColor = RGB(0,0,0);
}

void CTextTile::SetFont(BYTE s)
{
	size = s;
}

void CTextTile::SetCaption(LPCSTR str)
{
	title = str;
}

void CTextTile::SetStyle(DWORD s,COLORREF color)
{
	style = (s|DT_SINGLELINE);
	textColor = color;
}

void CTextTile::Draw(CDC* pDC)
{
	CFont* pf = CTextTile::UseFont(size);
	CFont* p0 = pDC->SelectObject(pf);

	CUITile::Draw(pDC);

	pDC->SetBkMode(TRANSPARENT);
	pDC->SetTextColor(textColor);
	pDC->DrawText(title,this,style);

	pDC->SelectObject(p0);
}
